package com.kolon.framework.view;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;

/**
 * 다운로드 뷰
 *	@author Stone
 *	@since 2011.07.06
 */
public class DownloadView extends AbstractView {

	/**
	 * 사용자 요청의 브라우저 얻는 함수 
	 * @param request	- 요청 객체
	 * @return
	 */
	private String getBrowser(HttpServletRequest request) {
		String header = request.getHeader("User-Agent");
		if (header.indexOf("MSIE") > -1) {
			return "MSIE";
		} else if (header.indexOf("Chrome") > -1) {
			return "Chrome";
		} else if (header.indexOf("Opera") > -1) {
			return "Opera";
		}
		return "Firefox";
	}

	/**
	 * ContentDisposition 설정하는 함수
	 * @param fileName	- 파일 명
	 * @param request	- 요청 객체
	 * @param response	- 응답 객체
	 * @throws Exception
	 */
	private void setDisposition(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
		String browser = getBrowser(request);
		String dispositionPrefix = "attachment; filename=";
		String encodedFilename = null;
		// 익스플로러
		if (browser.equals("MSIE")) {
			encodedFilename = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
		// 파이어폭스
		} else if (browser.equals("Firefox")) {
			encodedFilename = "\"" + new String(fileName.getBytes("UTF-8"), "8859_1") + "\"";
		// 오페라
		} else if (browser.equals("Opera")) {
			encodedFilename = "\"" + new String(fileName.getBytes("UTF-8"), "8859_1") + "\"";
		// 크롬
		} else if (browser.equals("Chrome")) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < fileName.length(); i++) {
				char c = fileName.charAt(i);
				if (c > '~') {
					sb.append(URLEncoder.encode("" + c, "UTF-8"));
				} else {
					sb.append(c);
				}
			}
			encodedFilename = sb.toString();
		} else {
			throw new IOException("Not supported browser");
		}
		response.setHeader("Content-Disposition", dispositionPrefix + encodedFilename);
		if ("Opera".equals(browser)){
			response.setContentType("application/octet-stream;charset=UTF-8");
		}
	}

	/**
	 * 파일 다운로드하는 함수
	 */
	public void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 다운로드 할 File 객체
		File file = (File) model.get("downloadFile");
		// 다운로드 할 파일 명
		String fileName = (String) model.get("fileName");
		// 파일 존재 여부
		if (file.exists() && file.isFile()) {
			String mimeType = "application/x-msdownload";
			// 마임 타입
			response.setContentType(mimeType);
			setDisposition(fileName, request, response);
			// 파일 크기
			response.setContentLength((int)file.length());
			BufferedInputStream in = null;
			BufferedOutputStream out = null;
			try {
				in = new BufferedInputStream(new FileInputStream(file));
				out = new BufferedOutputStream(response.getOutputStream());
				FileCopyUtils.copy(in, out);
				out.flush();
		} catch (Exception ex) {
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception ignore) {
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (Exception ignore) {
				}
			}
		}
		} else {
			throw new FileNotFoundException("file not found error.");
		}
	}

}
